<!-- 自定义键盘 -->
<template>
	<view class="vk-data-input-keyboard">
	<!-- 页面开始 -->
		<u-input
			v-if="showInput"
			:value="valueCom"
			:modelValue="valueCom"
			:placeholder="placeholder"
			type="select"
			:input-align="inputAlign"
			:custom-style="customStyle"
			@click="isShow = true" 
		></u-input>
		<u-keyboard 
			ref="uKeyboard"
			:value="isShow"
			:modelValue="isShow"
			:mode="mode" 
			:dot-enabled="dotEnabled"
			:tooltip="tooltip"
			:tips="tips"
			:show-tips="showTips"
			:cancel-btn="cancelBtn"
			:confirm-btn="confirmBtn"
			:mask="mask"
			:z-index="zIndex"
			:random="random"
			:safe-area-inset-bottom="safeAreaInsetBottom"
			:mask-close-able="maskCloseAble"
			:confirm-text="confirmText"
			:cancel-text="cancelText"
			@input="onPopupShow"
			@change="onChange"
			@backspace="onBackspace"
			@cancel="onCancel"
			@confirm="onConfirm"
		></u-keyboard>
	<!-- 页面结束 -->
	</view>
</template>

<script>
	/**
	 * keyboard 键盘
	 * @description 有多种键盘模式选择
	 * @property {String} placeholder 提示
	 * @property {String} mode 键盘的类型，number-数字键盘，card-身份证键盘，car-车牌号键盘
	 * @property {Number} precision 精度 默认2
	 * @property {Number} min 最小值
	 * @property {Number} max 最大值
	 * @property {String} input-align 输入框文字的对齐方式 可选 left right center 
	 * @property {Boolean} show-input 是否显示input 默认true
	 * @property {Boolean} dot-enabled 是否显示"."按键，只在mode=number时有效（默认true）
	 * @property {Boolean} tooltip 是否显示键盘顶部工具条（默认true）
	 * @property {Boolean} showTips 是否显示工具条中间的提示 默认true
	 * @property {String} tips 工具条中间的提示文字，见上方基本使用的说明，如不需要，请传""空字符
	 * @property {Boolean} cancel-btn 是否显示工具条左边的"取消"按钮（默认true）
	 * @property {Boolean} confirm-btn 是否显示工具条右边的"完成"按钮（默认true）
	 * @property {Boolean} mask 是否显示遮罩（默认true）
	 * @property {String} confirm-text 确认按钮的文字
	 * @property {String} cancel-text 取消按钮的文字
	 * @property {Number String} z-index 弹出键盘的z-index值（默认1075）
	 * @property {Boolean} random 是否打乱键盘按键的顺序（默认false）
	 * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配（默认false）
	 * @property {Boolean} mask-close-able 是否允许点击遮罩收起键盘（默认true）
	 * @event {Function} change 按键被点击(不包含退格键被点击)
	 * @event {Function} cancel 键盘顶部工具条左边的"取消"按钮被点击
	 * @event {Function} confirm 键盘顶部工具条右边的"完成"按钮被点击
	 * @event {Function} backspace 键盘退格键被点击
	 * @example <vk-data-input-keyboard v-model="form1.keyboard1" placeholder="请输入数字" mode="number" :precision="2" />
	 */
	export default {
		name: 'vk-data-input-keyboard',
		emits: ["update:modelValue", "input", "update:show", "cancel", "confirm", "change"],
		props: {
			// 表单值
			value: {

			},
			modelValue: {

			},
			customStyle: {
				type: Object
			},
			// 是否显示input
			showInput: {
				type: Boolean,
				default: true
			},
			show: {
				type: Boolean,
				default: false
			},
			// 提示
			placeholder: {
				type: String,
			},
			// 小数点位数
			precision: {
				type: Number,
				default: 2
			},
			// 最大值
			max: {
				type: Number,
				default: 1000000000000
			},
			// 最小值
			min: {
				type: Number,
			},
			// 键盘的类型，number-数字键盘，card-身份证键盘，car-车牌号键盘
			mode: {
				type: String,
				default: 'number'
			},
			// 是否显示键盘的"."符号
			dotEnabled: {
				type: Boolean,
				default: true
			},
			// 输入框文字的对齐方式
			inputAlign: {
				type: String
			},
			// 是否显示顶部工具条
			tooltip: {
				type: Boolean,
				default: true
			},
			// 是否显示工具条中间的提示
			showTips: {
				type: Boolean,
				default: true
			},
			// 工具条中间的提示文字
			tips: {
				type: String,
				default: ''
			},
			// 是否显示工具条左边的"取消"按钮
			cancelBtn: {
				type: Boolean,
				default: true
			},
			// 是否显示工具条右边的"完成"按钮
			confirmBtn: {
				type: Boolean,
				default: true
			},
			// 是否打乱键盘按键的顺序
			random: {
				type: Boolean,
				default: false
			},
			// 是否开启底部安全区适配，开启的话，会在iPhoneX机型底部添加一定的内边距
			safeAreaInsetBottom: {
				type: Boolean,
				default: true
			},
			// 是否允许通过点击遮罩关闭键盘
			maskCloseAble: {
				type: Boolean,
				default: true
			},
			// 是否显示遮罩，某些时候数字键盘时，用户希望看到自己的数值，所以可能不想要遮罩
			mask: {
				type: Boolean,
				default: true
			},
			// z-index值
			zIndex: {
				type: [Number, String],
				default: ''
			},
			// 取消按钮的文字
			cancelText: {
				type: String,
				default: '取消'
			},
			// 确认按钮的文字
			confirmText: {
				type: String,
				default: '确认'
			}
		},
		data: function() {
			// 组件创建时，进行数据初始化
			return {
				isShow: false
			};
		},
		mounted() {
			this.init();
		},
		methods: {
			// 初始化
			init() {

			},
			onPopupShow(value) {
				this.isShow = value;
			},
			// 向父组件发送更新value事件
			_updateValue(value) {
				this.$emit("input", value);
				this.$emit("update:modelValue", value);
				this.$emit("change", value);
			},
			// 按键被点击(点击退格键不会触发此事件)
			onChange(val) {
				// 将每次按键的值拼接到value变量中，注意+=写法
				let { valueCom: value } = this;
				value += val;
				value = this.getValue(value);
				this._updateValue(value);
				this.vibrateShort();
			},
			// 退格键被点击
			onBackspace(count) {
				let { valueCom: value } = this;
				if (value && value.length) {
					let num = 1;
					// 按的时间越长,删速度越快.
					if (count >= 8) {
						num = value.length > 6 ? 6 : value.length;
					} else if (count >= 5) {
						num = value.length > 4 ? 4 : value.length;
					} else if (count >= 3) {
						num = value.length > 2 ? 2 : value.length;
					}
					value = value.substr(0, value.length - num);
				}
				this._updateValue(value);
				this.vibrateShort();
			},
			vibrateShort() {
				// #ifdef MP-WEIXIN
				uni.vibrateShort();
				// #endif
			},
			onCancel() {
				this.$emit("cancel");
			},
			onConfirm() {
				this.$emit("confirm", this.valueCom);
			},
			getValue(value) {
				let vk = uni.vk;
				let { precision, mode, max } = this;
				if (mode == "number") {
					if (vk.pubfn.isNotNull(precision)) {
						// 小数位数限制
						let dianIndex = value.indexOf(".");
						if (dianIndex > -1) {
							value = value.substring(0, dianIndex + precision + 1);
						}
					}
					if (vk.pubfn.isNotNull(max)) {
						if (value > max) {
							value = max + "";
						}
					}
				}
				return value;
			},

		},
		// 监听器
		watch: {
			show(newVal) {
				this.isShow = newVal;
			},
			isShow(newVal) {
				let vk = uni.vk;
				this.$emit("update:show", newVal);
				if (!newVal) {
					// 判断最小值
					let { valueCom: value, mode, min } = this;
					if (mode == "number") {
						if (vk.pubfn.isNotNull(min) && value !== "") {
							if (value < min) {
								value = min + "";
								this._updateValue(value);
							}
						}
					}
				}
			},
			valueCom(newVal) {
				let { mode } = this;
				if (newVal.length == 0 && mode == "car" && this.$refs.uKeyboard) {
					this.$refs.uKeyboard.updateCarInputMode(false);
				}
			}
		},
		// 计算属性
		computed: {
			valueCom() {
				// #ifdef VUE2
				return this.value;
				// #endif

				// #ifdef VUE3
				return this.modelValue;
				// #endif
			},
		}
	};
</script>

<style lang="scss" scoped>
	.vk-data-input-keyboard {
		position: relative;
		-webkit-box-flex: 1;
		padding: 0px;
		border-color: rgb(220, 223, 230);
		text-align: left;
		width: 100%;
	}
</style>